多态与面向对象高级

第1章 多态

1.1 什么是多态?

多态指的是同一种事物多种形态

1.2 为什么要用多态?

用基类创建一套统一的规则,强制子类去遵循(使用抽象类实现),这样便可以

在不用考虑对象具体类型的前提下而直接使用对象下的方法

 

1.3 如何用多态?

示例:

class Animal:

    def eat(self):

        pass

 

    def drink(self):

        pass

 

    def run(self):

        pass

 

    def bark(self):

        pass

 

class Cat(Animal):

    def jiao(self):

        print('喵喵喵')

 

class Dog(Animal):

    def speak(self):

        print('汪汪汪')

 

class Pig(Animal):

    def han(self):

        print('哼哼哼')

 

c=Cat()

d=Dog()

p=Pig()

 
View Code

多态性:可以在不用考虑对象具体类型的前提下而直接使用对象下的方法

c.eat()

d.eat()

p.eat()

 

c.drink()

d.drink()

p.drink()

 

 

d.bark()

p.bark()

c.bark()

 

d.speak()

c.jiao()

p.han()

 

 

 

 

import abc #abstract class

class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod

    def eat(self):

        pass

 

    @abc.abstractmethod

    def drink(self):

        pass

 

    @abc.abstractmethod

    def run(self):

        pass

 

    @abc.abstractmethod

    def bark(self):

        pass
View Code

# obj=Animal() # 抽象基类本身不能被实例化

class Cat(Animal):

    def eat(self):

        print('cat eat')

 

    def drink(self):

        print('cat drink')

 

    def run(self):

        print('cat run')

 

    def bark(self):

        print('喵喵喵')

 

class Dog(Animal):

    def eat(self):

        print('dog eat')

 

    def drink(self):

        print('dog drink')

 

    def run(self):

        print('dog run')

 

    def bark(self):

        print('汪汪汪')

 

class Pig(Animal):

    def eat(self):

        print('pig eat')

 

    def drink(self):

        print('pig drink')

 

    def run(self):

        print('pig run')

 

    def bark(self):

        print('哼哼哼')

 

c=Cat()

d=Dog()

p=Pig()

 

 

c.bark()

d.bark()

p.bark()

 

 

def BARK(animal):

    animal.bark()

 

 

BARK(c)

BARK(d)

BARK(p)

 

 

 

s='hello'

l=[1,2,3]

t=(4,5,6)

 

s.__len__()

l.__len__()

t.__len__()

 

 

def LEN(obj):

    return obj.__len__()

 

print(LEN(s))

print(LEN(l))

print(LEN(t))

print(len(l))

print(len(s))

print(len(t))
View Code

1.4 鸭子类型

示例

class Foo:

    def f1(self):

        print('from foo.f1')

 

    def f2(self):

        print('from foo.f2')

 

class Bar:

    def f1(self):

        print('from bar.f1')

 

    def f2(self):

        print('from bar.f2')

 

 

obj1=Foo()

obj2=Bar()

 

 

obj1.f1()

obj1.f2()

 

obj2.f1()

obj2.f2()

 

 

 

 

class Disk:

    def read(self):

        print('disk read')

 

    def write(self):

        print('disk write')

 

 

class Txt:

    def read(self):

        print('txt read')

 

    def write(self):

        print('txt write')

 

 

class Process:

    def read(self):

        print('process read')

 

    def write(self):

        print('process write')

 

 

obj1=Disk()

obj2=Txt()

obj3=Process()

 

obj1.read()

obj2.read()

obj3.read()

 
View Code

 

 

第2章 classmethod与staticmethod

2.1 绑定方法

在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法

    绑定对象的方法特殊之处:

        应该由对象来调用,对象来调用,会自动将对象当作第一个参数传入 

2.2 classmethod

import settings   ##先创建一个文件

 

class People:

    def __init__(self,name,age):

        self.name=name

        self.age=age

 

    def tell(self):

        print('%s:%s' %(self.name,self.age))

 

    @classmethod

    def from_conf(cls):

        return cls(settings.NAME,settings.AGE)

 

 

p=People('egon',19)

p.tell()

 

p1=People(settings.NAME,settings.AGE)

p1.tell()

 

p2=People(settings.Name,settings.AGE)

p3=People('alex',74)

p3.tell()

 

print(People.from_conf)

p4=People.from_conf(People)

print(People.from_conf)

p4=People.from_conf()

p4.tell()

 
示例

 

2.3 staticmethod:非绑定方法,就是一个普通函数

特性:既不跟类绑定,也不跟对象绑定,这意味着谁都能用

谁来用都是一个普通函数,也就是说没有自动传值的特性

import settings

import hashlib

import time

 

class People:

    def __init__(self,name,age):

        self.uid=self.create_id()

        self.name=name

        self.age=age

 

    def tell(self):

        print('%s: %s:%s' %(self.uid,self.name,self.age))

 

    @classmethod

    def from_conf(cls):

        return cls(settings.NAME,settings.AGE)

 

    @staticmethod

    def create_id():

        m=hashlib.md5()

        m.update(str(time.clock()).encode('utf-8'))

        return m.hexdigest()

 

obj=People('egon',18)

# print(obj.uid,obj.name,obj.age)

# obj.tell()

 

# print(obj.create_id)

# print(People.create_id)

 

print(obj.create_id())

print(People.create_id())
View Code

 

2.4 内置函数补充(isinstance, issubclass)

示例:

class Foo:

    pass

   

obj=Foo()

print(isinstance(obj,Foo)) # 推荐使用该函数来判断一个函数的类型

print(type(obj) is Foo)

 

print(isinstance('abc',str))

print(isinstance(123,int))

 

print(issubclass(Foo,object))  #使用该函数来判断一个是不是一个对象
View Code

第3章 反射

#下述四个函数是专门用来操作类与对象属性的,如何操作?

#通过字符串来操作类与对象的属性,这种操作称为反射

class People:

    country="China"

    def __init__(self,name):

        self.name=name

    def tell(self):

        print('%s is aaa' %self.name)

 

obj=People('egon')
View Code

3.1 hasattr

hasattr() 函数用于判断对象是否包含对应的属性。

print(hasattr(People,'country'))

print('country' in People.__dict__)

 

print(hasattr(obj,'name'))

print(hasattr(obj,'country'))

print(hasattr(obj,'tell'))

 
示例

3.2 getattr

getattr() 函数用于返回一个对象属性值。

x=getattr(People,'country1',None)

print(x)

 

f=getattr(obj,'tell',None)#obj.tell

print(f == obj.tell)

f()

obj.tell()

 
示例

3.3 setattr

setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在

People.x=111

setattr(People,'x',111)

print(People.x)

 

obj.age=18

setattr(obj,"age",18)

print(obj.__dict__)
示例

3.4 delattr

delattr 函数用于删除属性。

del People.country

delattr(People,"country")

print(People.__dict__)

 

del obj.name

delattr(obj,"name")

print(obj.__dict__)

 
示例

3.5 练习

class Foo:

    def run(self):

        while True:

            cmd=input('cmd>>: ').strip()

            # print('%s run...' %cmd)

            if hasattr(self,cmd):

                func=getattr(self,cmd)

                func()

 

    def download(self):

        print('download....')

 

    def upload(self):

        print('upload...')

 

obj=Foo()

obj.run()
示例

第4章 __str__和__del__方法

示例

 __str__

class People:

    def __init__(self,name,age,sex):

        self.name=name

        self.age=age

        self.sex=sex

 

    def __str__(self):

        # print('========>')

        return '<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)

 

obj=People('egon',18,'male')

print(obj) #print(obj.__str__())

 

# l=list([1,2,3])

# print(l)
View Code

示例:

__del__

 模仿关闭系统资源

import time

 

class People:

    def __init__(self,name,age,sex):

        self.name=name

        self.age=age

        self.sex=sex

 

    def __del__(self): # 在对象被删除的条件下,自动执行

        print('__del__')

 

obj=People('egon',18,'male')

 

del obj #obj.__del__()

 

time.sleep(5)
View Code

示例:

class Mysql:

    def __init__(self,ip,port):

        self.ip=ip

        self.port=port

        self.conn=connect(ip,port) # 申请系统资源

 

    def __del__(self):

        self.conn.close()

 

obj=Mysql('1.1.1.1',3306)

 

 

class MyOpen:

    def __init__(self,filepath,mode="r",encoding="utf-8"):

        self.filepath=filepath

        self.mode=mode

        self.encoding=encoding

        self.fobj=open(filepath,mode=mode,encoding=encoding)

 

    def __str__(self):

        msg="""

        filepath:%s

        mode:%s

        encoding:%s

        """ %(self.filepath,self.mode,self.encoding)

        return msg

 

    def __del__(self):

        self.fobj.close()

 

# f=open('a.txt',mode='r',encoding='utf-8')

 

f=MyOpen('aaa.py',mode='r',encoding='utf-8')

# print(f.filepath,f.mode,f.encoding)

# print(f)

 

# print(f.fobj)

res=f.fobj.read()

print(res)

 
View Code

 

第5章 元类

示例:

code="""

global x

x=0

y=2

"""

global_dic={'x':100000}

local_dic={}

exec(code,global_dic,local_dic)

 

print(global_dic)

print(local_dic)

 

 

code="""

x=1

y=2

def f1(self,a,b):

    pass

"""

local_dic={}

exec(code,{},local_dic)

print(local_dic)
View Code

5.1 一切皆对对象

Chinese=type(...)

class Chinese:

    country="China"

 

    def __init__(self,name,age,sex):

        self.name=name

        self.age=age

        self.sex=sex

 

    def speak(self):

        print('%s speak Chinese' %self.name)

 

print(Chinese)

p=Chinese('egon',18,'male')

print(type(p))

 

print(type(Chinese))

元类:类的类就是元类,

我们用class定义的类使用来产生我们自己的对象的

内置元类type是用来专门产生class定义的类的

 

class Foo: #Foo=type(...)

    pass

 

print(type(Foo))

f=Foo

 

l=[Foo,]

print(l)
示例

5.2 用内置的元类type,来实例化得到我们的类

class_name='Chinese'

class_bases=(object,)

class_body="""

country="China"

def __init__(self,name,age,sex):

    self.name=name

    self.age=age

    self.sex=sex

def speak(self):

    print('%s speak Chinese' %self.name)

"""

class_dic={}

exec(class_body,{},class_dic)
示例

5.3 类的三大要素

print(class_name,class_bases,class_dic)

 

Chinese=type(class_name,class_bases,class_dic)

print(Chinese)

 

p=Chinese('egon',18,'male')

print(p.name,p.age,p.sex)
示例

5.4 储备知识__call__

class Foo:

    def __init__(self):

        pass

    def __str__(self):

        return '123123'

 

    def __del__(self):

        pass

 

 

    # 调用对象,则会自动触发对象下的绑定方法__call__的执行,

    # 然后将对象本身当作第一个参数传给self,将调用对象时括号内的值

    #传给*args与**kwargs

    def __call__(self, *args, **kwargs):

        print('__call__',args,kwargs)


obj=Foo()

# print(obj)


obj(1,2,3,a=1,b=2,c=3) #

5.5 自定义元类

class Mymeta(type):

    # 来控制类Foo的创建

    def __init__(self,class_name,class_bases,class_dic): #self=Foo

        # print(class_name)

        # print(class_bases)

        # print(class_dic)

        if not class_name.istitle():

            raise TypeError('类名的首字母必须大写傻叉')

 

        if not class_dic.get('__doc__'):

            raise TypeError('类中必须写好文档注释,大傻叉')

 

        super(Mymeta,self).__init__(class_name,class_bases,class_dic)

 

    # 控制类Foo的调用过程,即控制实例化Foo的过程

    def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={}

        # print(self)

        # print(args)

        # print(kwargs)

 

        #1 造一个空对象obj

        obj=object.__new__(self)

 

        #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__

        self.__init__(obj,*args,**kwargs)

 

        return obj

 

 

 

#Foo=Mymeta('Foo',(object,),class_dic)

class Foo(object,metaclass=Mymeta):

    """

    文档注释

    """

    x=1

    def __init__(self,y):

        self.Y=y

 

    def f1(self):

        print('from f1')

 

 

obj=Foo(1111) #Foo.__call__()

 

# print(obj)

# print(obj.y)

# print(obj.f1)

# print(obj.x)
示例

5.6 单例模式

import settings

 

class MySQL:

    __instance=None

    def __init__(self,ip,port):

        self.ip=ip

        self.port=port

 

    @classmethod

    def singleton(cls):

        if not cls.__instance:

            obj=cls(settings.IP, settings.PORT)

            cls.__instance=obj

        return cls.__instance

 

obj1=MySQL('1.1.1.2',3306)

obj2=MySQL('1.1.1.3',3307)

obj3=MySQL('1.1.1.4',3308)

 

# obj4=MySQL(settings.IP,settings.PORT)

# print(obj4.ip,obj4.port)

 

obj4=MySQL.singleton()

obj5=MySQL.singleton()

obj6=MySQL.singleton()

 

print(obj4 is obj5 is obj6)
示例

 

posted @ 2018-05-14 19:03  Jacob先生  阅读(118)  评论(0编辑  收藏  举报